package com.studio.framework.controller.monitorSystem.monitor;

import com.studio.framework.controller.monitorSystem.bean.ErrorLog;
import com.studio.framework.controller.monitorSystem.dto.FindMonitorResDto;
import com.studio.framework.controller.monitorSystem.service.ErrorLogService;
import com.studio.framework.controller.monitorSystem.service.ServerGroupService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author jujh
 * @Date 2018/7/17
 * 监控系统是否是正常运行状态
 */
@Component
public class MonitorUtil {


        private static Logger logger = Logger.getLogger(MonitorUtil.class);

    //@Autowired
    //private RedisUtil redisUtil;

    @Autowired
    private ServerGroupService serverGroupService;

    @Autowired
    private ErrorLogService errorLogService;

    @PostConstruct
    public void beginThread() {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
        int delay = Integer.parseInt(this.initDelay);
        int period = Integer.parseInt(this.period);
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            public void run() {
                //延迟1小时后，每2小时执行一次
                monitorServer();
            }
        }, delay, period, TimeUnit.MINUTES);
    }

    /**
     * 监控系统
     */
    private void monitorServer() {
        List<FindMonitorResDto> monitorResDtos = serverGroupService.findMonitorData();
        if (monitorResDtos != null && !monitorResDtos.isEmpty()) {
            for (FindMonitorResDto dto : monitorResDtos) {
                String ip = dto.getIp();
                int port = dto.getPort();
                String phones = dto.getPhone();
                String groupName = dto.getGroupName();
                Boolean runState = isHostConnectable(ip, port);
                // false 服务器异常
                if (!runState) {
                    // Object ipPort = redisUtil.get(ip + port);
                    // if (ipPort == null) {//代表没有执行过
                    //redisUtil.set(ip + port, ip + port, 3600);
                    logger.error("服务器：" + ip + ",端口:" + port + "运行异常，请联系管理员。");
                    //定义发送内送
                    String content = groupName + "：服务器:" + ip + ",端口:" + port + "运行异常,请及时处理。";
                    //记录日志
                    saveErrorLog(groupName, dto.getGroupId(), dto.getServerName(), ip, port, content);
                    //发送短信
                    if (StringUtils.isNoneBlank(phones)) {
                        for (String phone : phones.split(",")) {
                            //{1}:服务器:{2},端口:{3},运行异常,请及时处理.
                            SendSMSUtil.sendMsg("309061", phone, new String[]{groupName, ip, port + ""}, this.smsURL, this.smsPort);
                        }
                    }
                    // }
                }
            }
        }
    }

    private static boolean isHostConnectable(String host, int port) {
        Socket socket = new Socket();
        try {
            socket.connect(new InetSocketAddress(host, port));
        } catch (IOException e) {
            return false;
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    private void saveErrorLog(String groupName, String groupId, String serverName, String ip, int port, String content) {

        ErrorLog errorLog = new ErrorLog();
        errorLog.setGroupId(groupId);
        errorLog.setGroupName(groupName);
        errorLog.setServerName(serverName);
        errorLog.setIp(ip);
        errorLog.setPort(port);
        errorLog.setErrorMsg(content);
        errorLog.setCreateDate(new Date());
        errorLogService.create(errorLog);

    }


    //短信服务地址
    @Value("${smsURL}")
    private String smsURL;
    //短信服务端口
    @Value("${smsPort}")
    private String smsPort;
    //设置线程延迟时间
    @Value("${thread.initdelay}")
    private String initDelay;
    //设置线程执行周期
    @Value("${thread.period}")
    private String period;

}
